package com.example.guet_assistant.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.guet_assistant.constant.MessageConstant;
import com.example.guet_assistant.context.BaseContext;
import com.example.guet_assistant.domain.dto.UserAccountBindingDTO;
import com.example.guet_assistant.domain.dto.UserFromDTO;
import com.example.guet_assistant.domain.dto.WxLoginDTO;
import com.example.guet_assistant.domain.po.User;
import com.example.guet_assistant.exception.LoginFailedException;
import com.example.guet_assistant.exception.RegisterFailedException;
import com.example.guet_assistant.properties.WeChatProperties;
import com.example.guet_assistant.result.Result;
import com.example.guet_assistant.service.IUserService;
import com.example.guet_assistant.mapper.UserMapper;
import com.example.guet_assistant.utils.HttpClientUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author Lenovo
* @description 针对表【user】的数据库操作Service实现
* @createDate 2024-11-03 15:53:49
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>  implements IUserService {

    public static final String WX_LOGIN="https://api.weixin.qq.com/sns/jscode2session";

    @Autowired
    private WeChatProperties  weChatProperties;
    @Autowired
    private UserMapper userMapper;


    private static  final CopyOptions options = CopyOptions.create().setIgnoreNullValue(true).setOverride(false);

    @Override
    public Integer login(Long studentId, String password) {
        User user = getUserByStudentIdAndPassword(studentId, password);
        if (user==null) {
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }
        return user.getId();
    }


    @Override
    public void register(UserFromDTO userFromDTO) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getStudentId, userFromDTO.getStudentId());
        if (getOne(lambdaQueryWrapper)!=null) {
            throw new RegisterFailedException(MessageConstant.REGISTER_FAILED);
        }
//      md5加密处理密码
        userFromDTO.setPassword(DigestUtils.md5DigestAsHex(userFromDTO.getPassword().getBytes()));
        save(BeanUtil.copyProperties(userFromDTO, User.class));
    }

    @Override
    public Integer login(WxLoginDTO wxLoginDTO) {
        String openId = getOpenId(wxLoginDTO.getCode());
        if(openId==null){
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                                 lambdaQueryWrapper.eq(User::getWxId,openId);
        User user = getOne(lambdaQueryWrapper);
        if(user==null){
            user=User.builder().wxId(openId).build();
              save(user);
        }
        return user.getId();
    }

    @Override
    public void userAccountBinding(UserAccountBindingDTO userAccountBindingDTO) {
          System.out.println(userAccountBindingDTO);
          Integer currentId = BaseContext.getCurrentId();
          User currUser =getById(currentId);
          User user;
          String openId="";
          Integer userId;
          if(userAccountBindingDTO.getCode()==null){
                 user = getUserByStudentIdAndPassword(userAccountBindingDTO.getStudentId(),userAccountBindingDTO.getPassword());
                 userId=user.getId();
          }
          else {
                 openId = getOpenId(userAccountBindingDTO.getCode());
                 //openId="test";
                 user=lambdaQuery().eq(User::getWxId,openId).one();
                 userId=user.getId();
          }
        String password = userAccountBindingDTO.getPassword();
        if(BeanUtil.isEmpty(user)){
            if (password==null){ user = User.builder().studentId(userAccountBindingDTO.getStudentId()).password(null).wxId(openId).build();}
            else {
                 user = User.builder().studentId(userAccountBindingDTO.getStudentId()).password(DigestUtils.md5DigestAsHex(password.getBytes())).wxId(openId).build();
            }
              BeanUtil.copyProperties(user,currUser,options);
              currUser.setId(currentId);
              updateById(currUser);
        }
        else {
              user.setWxId(openId);
              user.setStudentId(userAccountBindingDTO.getStudentId());
            if (password==null){
                user.setPassword(null);
            }
            else {
                user.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
            }

              System.out.println(user);
              System.out.println(currUser);
              BeanUtil.copyProperties(user,currUser,options);
              System.out.println(currUser);
              currUser.setId(currentId);
              updateById(currUser);
              removeById(user.getId());
          }
    }

    @Override
    public Result<Map<Integer, String>> getUserList(){
        List<User> users = userMapper.selectList(new QueryWrapper<>());
        Map<Integer, String> returnMap = new HashMap<>();
        for(User user : users){
            Integer id = user.getId();
            String username = user.getUsername();
            if(username != null)
                returnMap.put(id, username);
        }
        return Result.success(returnMap);
    }






    //根据学号和密码查找user对象
    private User getUserByStudentIdAndPassword(Long studentId,String password){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getStudentId, studentId)
                .eq(User::getPassword, DigestUtils.md5DigestAsHex(password.getBytes()));
          return getOne(lambdaQueryWrapper);
    }




    //获取用户的openId
    private String  getOpenId(String  code){
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("appid", weChatProperties.getAppid());
        hashMap.put("secret",weChatProperties.getSecret());
        hashMap.put("js_code",code);
        hashMap.put("grant_type","authorization_code");
        String s = HttpClientUtil.doGet(WX_LOGIN, hashMap);
        JSONObject jsonObject = JSON.parseObject(s);
        return jsonObject.getString("openid");
    }




}




